/** @ingroup terminal
 * @file terminal.h
 * @brief functions to manipulate the screen buffer
 *
 * @author cameris camerisdump@gmail.com
 */

#ifndef _TERMINAL_H_
#define _TERMINAL_H_

//#include "lcd.h"
#include <stdint.h>

#define STATUS_TIME 1000 /**< @brief time to display status line in ms */
#define TERM_BLINK_MS 800 /**< @brief blink toogle time in ms */

/** @brief character buffer */
struct charbuf {
	uint8_t ch; /**< @brief character */
	uint8_t fgcolor; /**< @brief foreground color index */
	uint8_t bgcolor; /**< @brief background color index */
	unsigned underline:1; /**< @brief print underline */
	unsigned inverse:1; /**< @brief swap background and foreground color */
	unsigned blink:1; /**< @brief blinking character */
	unsigned bold:1; /**< @brief use bold font */
	unsigned font:3; /**< @brief font */
};

/** @brief terminal settings */
struct terminal {
	struct charbuf cb; /**< @brief active char options */
	uint8_t cx; /**< @brief cursor current column */
	uint8_t cy; /**< @brief cursor current line */
	uint8_t mtop; /**< @brief current top margin */
	uint8_t mbottom; /**< @brief current bottom margin */
	unsigned int localecho:1; /**< @brief keyboard keys are send to input parser */
	unsigned int autowrap:1; /**< @brief moves to first column in next line
							   when hitting right margin */
	unsigned int origin:1; /**< @brief absolute position is top left corner of
							 margin instead of terminal */
	unsigned int insert:1; /**< @brief new chars are inserted instead of
							 overwrite existing characters */
	unsigned int newline:1; /**< @brief LF, VT and FF also move to first column */
	unsigned int visiblecursor:1; /**< @brief show cursor */
	unsigned int drawcursor:1; /**< @brief temporarily enable/disable cursor */
	unsigned int showcontrol:1; /**< @brief show characters instead of interpret them */
	unsigned int kp_app:1; /**< @brief keypad key application mode */
	unsigned int backarrow:1; /**< @brief backarrow key mode */
	unsigned int cursorkey:1; /**< @brief cursor key mode */
	unsigned int sendc1:1; /**< @brief send C1 or C0-replacement */
	unsigned int blink_do:1; /**< @brief if set redraw blinking characters */
	unsigned int blink:1; /**< @brief draw space or character */
};

/** @name reset functions
 * @{ */
void term_reset(void);
void term_init(void);
/* @} */

/** @name tab functions
 * @{ */
void term_tab_set(uint_fast8_t x);
void term_tab_clear(uint_fast8_t mode);
void term_tab_move(int_fast8_t n);
/* @} */

/** @name cursor functions
 * @{ */
int_fast8_t term_move_cursor(int_fast8_t dx, int_fast8_t dy);
void term_set_cursor_position(uint_fast8_t x, uint_fast8_t y);

uint8_t term_get_cursor_line(void);
uint8_t term_get_cursor_col(void);

void term_save_cursor(void);
void term_restore_cursor(void);
/* @} */

/** @name general terminal functions
 * @{ */
void term_print(uint8_t ch);
void term_status_line(uint8_t *str);
void term_redraw_blink(void);

void term_scroll(int_fast8_t n);

void term_set_margins(uint_fast8_t top, uint_fast8_t bottom);

uint8_t term_get_top_margin(void);
uint8_t term_get_bottom_margin(void);

uint8_t term_get_last_col(void);
uint8_t term_get_last_line(void);
/* @} */

/** @name erase functions
 * @{ */
void term_erase_display(uint_fast8_t erasemode);
void term_erase_line(uint_fast8_t erasemode);
void term_erase_char(uint_fast8_t n);

void term_del_char(uint_fast8_t n);
void term_ins_char(uint_fast8_t n);

void term_ins_or_del_line(int_fast8_t n);
/* @} */

/** @name character attribute functions
 * @{ */
void term_reset_char_attr(void);

void term_set_char_bold(uint_fast8_t b);
void term_set_char_underline(uint_fast8_t b);
void term_set_char_inverse(uint_fast8_t b);
void term_set_char_blink(uint_fast8_t b);

uint_fast8_t term_get_char_bold(void);
/* @} */

/** @name terminal mode functions
 * @{ */
void term_set_local_echo(uint_fast8_t b);
void term_set_autowrap(uint_fast8_t b);
void term_set_insertmode(uint_fast8_t b);
void term_set_originmode(uint_fast8_t b);
void term_set_newlinemode(uint_fast8_t b);
void term_set_show_control_chars(uint_fast8_t b);
void term_set_cursor_visible(uint_fast8_t b);
void term_set_screenmode(uint_fast8_t b);
void term_set_kp_application(uint_fast8_t b);
void term_set_backarrowmode(uint_fast8_t b);
void term_set_cursorkeymode(uint_fast8_t b);
void term_set_sendc1(uint_fast8_t b);

uint_fast8_t term_get_show_control_chars(void);
uint_fast8_t term_get_local_echo(void);
uint_fast8_t term_get_newlinemode(void);
uint_fast8_t term_get_originmode(void);
uint_fast8_t term_get_kp_application(void);
uint_fast8_t term_get_backarrowmode(void);
uint_fast8_t term_get_cursorkeymode(void);
uint_fast8_t term_get_sendc1(void);
/* @} */

/** @name color functions
 * @{ */
void term_set_fgcolor(uint8_t col);
void term_set_bgcolor(uint8_t col);

void term_reset_fgcolor(void);
void term_reset_bgcolor(void);

uint8_t term_get_fgcolor(void);
/* @} */

#endif
